import { h, defineComponent, markRaw, TransitionGroup, toRaw, watch, shallowRef } from 'vue'
import ContainerNode from '../../ItemNode/ContainerNode'
import classes from '../../ItemNode/ItemNode.module.css'
import {
  ElButton,
  ElScrollbar,
  ElText,
  ElConfigProvider,
  ElColorPicker,
  ElInput
} from 'element-plus'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'

export default class NPage extends ContainerNode {
  isNPage = true
  static preview = false

  constructor(node?: NPage) {
    super(node)

    if (!node) {
      this.path = './components/NPage/NPage.tsx'
      this.name = '页面'

      this.props.name = '新页面'

      const style = this.props.style
      this.props.style = {
        ...style,
        width: '1000px',
        flexShrink: '0',
        flexGrow: '0',
        backgroundColor: '#fff',
        height: '800px',
        // perspective: 0, // 设置 perspective: 0 会让NTreeSelect出现下拉显示bug
        transform: 'none',
        inset: 'auto'
      }

      this.props.themeColor = 'hsl(0, 0%, 100%)'

      this.setTheme(this.props.themeColor)
    }

    const pComponent = this.component
    this.component = markRaw(
      defineComponent(
        (props) => {
          const srollbarRef = shallowRef()
          // 处理重置后滚动条问题
          watch(
            () => this.props.style.transform,
            () => {
              setTimeout(() => {
                srollbarRef.value?.update()
              }, 2000)
            }
          )

          return () => (
            <pComponent>
              <ElConfigProvider locale={zhCn}>
                <ElScrollbar ref={srollbarRef} noresize>
                  <TransitionGroup name="list">
                    {() => this.children.map((child, i) => h(child.component, { key: child.uuid }))}
                  </TransitionGroup>
                </ElScrollbar>
              </ElConfigProvider>
            </pComponent>
          )
        },
        {
          name: 'NPage'
        }
      )
    )

    const pParams = this.params
    this.params = markRaw(
      defineComponent(() => {
        return () => (
          <pParams>
            {() => [
              <div class={classes['params-item']}>
                <ElText class={classes['params-item-label']} type="info">
                  页面名
                </ElText>
                <div class={classes['params-item-content']}>
                  <ElInput v-model={this.props.name} size="small"></ElInput>
                </div>
              </div>,
              <div class={classes['params-item']}>
                <ElText class={classes['params-item-label']} type="info">
                  主题色
                </ElText>
                <div class={classes['params-item-content']}>
                  <ElColorPicker
                    modelValue={this.props.themeColor}
                    onUpdate:modelValue={(v) => {
                      this.props.themeColor = v || 'hsla(223, 0%, 100%, 1)'
                      this.setTheme(this.props.themeColor)
                    }}
                    colorFormat="hsl"
                    show-alpha
                    size="small"
                    teleported={false}
                  ></ElColorPicker>
                </div>
              </div>,
              <div class={classes['params-item']}>
                <ElText class={classes['params-item-label']} type="info">
                  缩放
                </ElText>
                <div class={classes['params-item-content']}>
                  <ElButton
                    onClick={() => (this.props.style.transform = '')}
                    type="primary"
                    size="small"
                  >
                    重置
                  </ElButton>
                </div>
              </div>
            ]}
          </pParams>
        )
      })
    )
  }

  // 导出时清除页面容器的位移和缩放
  resetStyle() {
    this.props.style.transform = ''
    this.props.style.position = 'relative'
    this.props.style.left = this.props.style.top = 'auto'
  }

  setTheme(themeColor) {
    let [, hue, saturation, lightness, alpha] = themeColor.match(
      /hsla?\((\d{0,3})[, ]+(\d+)%[, ]+(\d+)%[, ]*?([\d\.]*?)\)/i
    )

    hue = Number.parseFloat(hue)
    saturation = Number.parseFloat(saturation)
    lightness = Number.parseFloat(lightness)
    alpha = Number.parseFloat(alpha)

    const lightness5 = Math.min(Math.max(0, lightness > 50 ? lightness - 5 : lightness + 5), 100)
    const lightness10 = Math.min(Math.max(0, lightness > 50 ? lightness - 10 : lightness + 10), 100)
    const lightness15 = Math.min(Math.max(0, lightness > 50 ? lightness - 15 : lightness + 15), 100)
    const lightness20 = Math.min(Math.max(0, lightness > 50 ? lightness - 20 : lightness + 20), 100)
    const lightness25 = Math.min(Math.max(0, lightness > 50 ? lightness - 25 : lightness + 25), 100)
    const lightness30 = Math.min(Math.max(0, lightness > 50 ? lightness - 30 : lightness + 30), 100)

    const styleVar = {
      '--el-color-primary': `hsla(${hue}, ${saturation}%, 50%, 1)`,
      // '--el-text-color-regular': lightness > 50 ? '#333' : '#ccc',
      // '--el-text-color-primary': lightness > 50 ? '#333' : '#ccc',
      // '--el-fill-color-blank': themeColor,
      // '--el-fill-color-light': `hsla(${hue}, ${saturation}%, ${lightness5}%, ${alpha})`,
      // '--el-fill-color-lighter': `hsla(${hue}, ${saturation}%, ${lightness10}%, ${alpha})`,
      // '--el-bg-color-overlay': themeColor,
      // '--el-bg-color': themeColor,
      // '--el-border-color': `hsla(${hue}, ${saturation}%, ${lightness15}%, ${alpha})`,
      // '--el-border-color-light': `hsla(${hue}, ${saturation}%, ${lightness20}%, ${alpha})`,
      // '--el-border-color-lighter': `hsla(${hue}, ${saturation}%, ${lightness25}%, ${alpha})`,
      // '--el-border-color-hover': `hsla(${hue}, ${saturation}%, ${lightness30}%, ${alpha})`,
      // '--el-border': `1px solid var(--el-border-color)`,
      '--ec-text-color': lightness > 50 ? '#333' : '#ccc',
      '--ec-border-color': `hsla(${hue}, ${saturation}%, ${lightness15}%, ${alpha})`,
      '--ec-background-color': themeColor
    }

    Object.assign(this.props.style, styleVar)
  }

  getAllNodes() {
    const allNodes = []
    this.traverse((node) => allNodes.push(toRaw(node)))

    return allNodes
  }

  toVue(): SfcObj {
    const sfcObj = super.toVue()

    sfcObj.imports = {
      ...sfcObj.imports,
      ['element-plus']: {
        ElConfigProvider: 'ElConfigProvider',
        ElScrollbar: 'ElScrollbar'
      },
      ['element-plus/dist/locale/zh-cn.mjs']: {
        default: 'zhCn'
      }
    }

    sfcObj.template = sfcObj.template.replace(
      '<slot></slot>',
      `
  <ElConfigProvider :locale="zhCn">
    <ElScrollbar>
      ${this.children.map((child) => child.uuid).join('\n    ')}
    </ElScrollbar>
  </ElConfigProvider>
      `
    )

    return sfcObj
  }
}
